<template>
  <div class="game">
    <h2>tic tac toe</h2>
    <div class="board">
      <div class="row" v-for="(row, rowIndex) in board" :key="rowIndex">
        <div
          class="grid"
          v-for="(grid, gridIndex) in row"
          :key="gridIndex"
          @click="play(rowIndex, gridIndex)"
        >{{grid | renderGrid}}</div>
      </div>
    </div>
    当前玩家: {{player | renderGrid}}
  </div>
</template>

<script>
export default {
  data() {
    return {
      player: 1,
      board: [
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
      ],
    };
  },
  computed: {
    boardRotated() {
      return this.board.map((row, rowIndex) => {
        return row.map((grid, gridIndex) => {
          return this.board[gridIndex][rowIndex];
        });
      });
    },
  },
  methods: {
    play(x, y) {
      this.board = this.board.map((row, rowIndex) => {
        return row.map((grid, gridIndex) => {
          if (x == rowIndex && y == gridIndex && grid === 0) return this.player;
          return grid;
        });
      });
      this.player *= -1;
      setTimeout(() => {
        this.check();
      }, 50);
    },
    check() {
      const winner = this.checkRow() || this.checkCol() || this.checkEdge();
      if (winner) {
        if (confirm(`${winner == 1 ? "X" : "O"} 得到了胜利`)) {
          this.reset();
        }
      }
      if (
        this.board.flat().find((grid) => {
          return grid == 0;
        }) === undefined
      ) {
        if (confirm(`平局`)) {
          this.reset();
        }
      }
    },
    checkRow() {
      const winLine = this.board.find((row) => {
        return row[0] !== 0 && row[0] == row[1] && row[1] == row[2];
      });
      if (winLine) return winLine[0];
    },
    checkCol() {
      const winLine = this.boardRotated.find((row) => {
        return row[0] !== 0 && row[0] == row[1] && row[1] == row[2];
      });
      if (winLine) return winLine[0];
    },
    checkEdge() {
      if (
        this.board[0][0] == this.board[1][1] &&
        this.board[1][1] == this.board[2][2]
      )
        return this.board[0][0];
      if (
        this.board[0][2] == this.board[1][1] &&
        this.board[1][1] == this.board[2][0]
      )
        return this.board[0][2];
    },
    reset() {
      this.player = 1;
      this.board = [
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
      ];
    },
  },
  filters: {
    renderGrid(grid) {
      if (grid == -1) return "O";
      if (grid == 1) return "X";
      return "";
    },
  },
};
</script>

<style lang="less" scoped>
.game {
  padding: 24px;
  font-size: 24px;
  .board {
    margin-bottom: 24px;
    display: flex;
    flex-direction: column;
    .row {
      display: flex;
      .grid {
        width: 88px;
        line-height: 88px;
        height: 88px;
        font-size: 33px;
        color: #333;
        font-weight: bold;
        text-align: center;
        border: 1px solid #888;
        background: pink;
        &:nth-child(2n) {
          background: #fff;
        }
      }
      &:nth-child(2n) {
        .grid {
          background: #fff;
          &:nth-child(2n) {
            background: pink;
          }
        }
      }
    }
  }
}
</style>